package com.funmi.lizip.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.funmi.lizip.common.base.R;
import com.funmi.lizip.common.base.ResultCode;
import com.funmi.lizip.common.exception.ApplicationException;
import com.funmi.lizip.entity.Device;
import com.funmi.lizip.entity.dto.device.DeviceAddRequest;
import com.funmi.lizip.entity.dto.device.DeviceQueryRequest;
import com.funmi.lizip.entity.dto.device.DeviceUpdateRequest;
import com.funmi.lizip.entity.vo.DeviceVo;
import com.funmi.lizip.service.DeviceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zzy
 * @since 2022-11-02
 */
@Api(tags = "有害生物防治模块")
@RestController
@RequestMapping("/devices")
@Slf4j
public class DeviceController {

    @Autowired
    private DeviceService deviceService;

    /**
     * 保存
     */
    @ApiOperation(value = "设备的新增")
    @PostMapping("")
    public R addDevice(@RequestBody DeviceAddRequest request) {
        if (request == null) {
            throw new ApplicationException(ResultCode.NOT_FOUND);
        }
        Device device = new Device();

        request.setCreateAt(LocalDateTime.now());
        BeanUtils.copyProperties(request, device);
        boolean save = deviceService.save(device);
        log.info("[返回后的数据]save{}", save);
        if (save) {
            return R.success().message("新增成功");
        } else {
            throw new ApplicationException("新增失败");
        }


    }

    /**
     * 修改
     */
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "设备的修改")
    @PutMapping("/{id}")
    public R updateDevice(@RequestBody(required = false) DeviceUpdateRequest request) {
        if (request == null || request.getId() == null) {
            throw new ApplicationException(ResultCode.NOT_FOUND);
        }
        Device device = new Device();
        BeanUtils.copyProperties(request, device);
        boolean update = deviceService.updateById(device);

        if (update) {
            return R.success().message("修改成功");
        } else {
            throw new ApplicationException("修改失败");
        }
    }


    /**
     * 删除
     */
    @ApiOperation(value = "设备的删除")
    @DeleteMapping("/{id}")
    public R deleteDevice(@PathVariable int id) {
        if (id <= 0) {
            throw new ApplicationException(ResultCode.FILE_DELETE_ERROR);
        }
        boolean result = deviceService.removeById(id);
        if (result) {
            return R.success().message("删除成功");
        } else {
            return R.fail().message("删除失败");
        }


    }



    /**
     * 导出
     */
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation("设备数据导出到excel")
    @GetMapping("/exportListExcel")
    public void exportListExcel(@RequestParam(required = false) String site,
                                @RequestParam(required = false) String type,
                                @RequestParam(required = false) LocalDateTime shotAt,
                                @RequestParam(required = false) LocalDateTime endAt,
                                HttpServletResponse response) throws IOException {
        DeviceQueryRequest device = new DeviceQueryRequest();
        device.setShotAt(shotAt);
        device.setEndAt(endAt);
        device.setType(type);
        device.setSite(site);

        List<Device> list = deviceService.getAll(device);
        //List<Device> list = deviceService.getAll(device);
        String fileName = URLEncoder.encode("设备清单.xlsx", "UTF-8");
        EasyExcel.write(fileName, Device.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("设备清单清单")
                .doWrite(list);
        File file = new File(fileName);
        // 通知浏览器进行文件下载
        response.setContentType("application/x-download");
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
        InputStream stream = new FileInputStream(file);
        ServletOutputStream out = response.getOutputStream();
        byte buff[] = new byte[1024];
        int length = 0;
        while ((length = stream.read(buff)) > 0) {
            out.write(buff, 0, length);
        }

        stream.close();
        out.close();
        out.flush();
    }


    /**
     * 根据输入进行检索
     */
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("根据输入进行检索")
    @GetMapping("")
    public R queryList(DeviceQueryRequest request) {
        long size = 5;
        long current = 1;
        Device deviceQuery = new Device();
        if (request != null) {
            BeanUtils.copyProperties(request, deviceQuery);
            current = request.getPage();
            size = request.getPageSize();
        }
        deviceQuery.setSite(null);

        QueryWrapper<Device> qw = new QueryWrapper<>(deviceQuery);
        // 让type为空也能查询
        if (request != null && request.getType() != null) {
            qw.eq("type", deviceQuery.getType());

        }
        LocalDateTime startTime = request.getShotAt();
        LocalDateTime endTime = request.getEndAt();

        // 根据时间范围查询
        if (startTime != null) {
            qw.ge("create_at", startTime);
        }
        if (endTime != null) {
            qw.le("create_at", endTime);
        }
        if (!ObjectUtils.isEmpty(request) && !ObjectUtils.isEmpty(request.getSite())){
            qw.like("site", request.getSite());
        }
        // 根据创建时间排序
        qw.select().orderByDesc("create_at");


        Page<Device> devicePage = deviceService.page(new Page<>(current, size), qw);

        PageDTO<DeviceVo> deviceVoPage = new PageDTO(devicePage.getCurrent(), devicePage.getSize(), devicePage.getTotal());

        List<DeviceVo> deviceVoList = devicePage.getRecords().stream().map(device -> {
            DeviceVo deviceVo = new DeviceVo();
            BeanUtils.copyProperties(device, deviceVo);
            return deviceVo;
        }).collect(Collectors.toList());
        deviceVoPage.setRecords(deviceVoList);

        return R.success().data(deviceVoPage);

    }


    @ApiOperation(value = "根据设备id获取信息")
    @ApiImplicitParam(name = "id", value = "设备id", dataTypeClass = String.class, required = true)
    @GetMapping("/{id}")
    public R position(@PathVariable Integer id) {
        Device device = deviceService.getById(id);
        return R.success().data(device);
    }


    @ApiOperation(value = "设备下线")
    @PostMapping(value = {"/offline"}, produces = {"application/json;charset=UTF-8"})
    public R RobeInstrumentMessage(@RequestBody HashMap<String, Object> stringObjectHashMap) {
        return deviceService.robeInstrumentMessage(stringObjectHashMap);
    }


//    @GetMapping("/downLoad")
//    public void excel(HttpServletResponse response,DeviceQueryRequest request){
//        deviceService.downLoad(response,request);
//    }
}

